#include "config.h"

#include <sys/statvfs.h>
#include <sys/epoll.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <semaphore.h>
#include <errno.h>
#include <sys/statfs.h>

#define DBG_SUBSYS S_LIBSTORAGE

#include "sysutil.h"
#include "configure.h"
#include "../../schedule/cpuset.h"
#include "../replica/clock/clock.h"
#include "dbg.h"

typedef struct {
        int threadid;
        int count;
} test_clock_arg_t;

static void *__clock_set_thread(void *_arg)
{
        int ret;
        uint64_t i;
        chkid_t chkid;
        test_clock_arg_t *arg = _arg;
        vclock_t vclock;

        vclock.clock = 0;
        vclock.vfm = 0;
        while (1) {
                for (i = 0; i < arg->count; i++) {
                        chkid.id = i;
                        chkid.type = 3;
                        chkid.idx = 0;
                        vclock.clock++;
                        ret = clock_set(&chkid, &vclock, 0);
                        if (unlikely(ret))
                                GOTO(err_ret, ret);
                }
                printf("thread %d set ok, clock %lu, retry...\n", arg->threadid, vclock.clock);
        }

        return NULL;
err_ret:
        YASSERT(0);
        return NULL;
}

int test_clock_set_start(int threadid, int count)
{
        int ret;
        pthread_t th;
        pthread_attr_t ta;
        test_clock_arg_t *arg;

        ret = ymalloc((void**)&arg, sizeof(test_clock_arg_t));
        if (unlikely(ret))
                GOTO(err_ret, ret);

        (void) pthread_attr_init(&ta);
        (void) pthread_attr_setdetachstate(&ta, PTHREAD_CREATE_DETACHED);
        arg->threadid = threadid;
        arg->count = count;
        ret = pthread_create(&th, &ta, __clock_set_thread, (void *)arg);
        if (unlikely(ret))
                GOTO(err_ret, ret);

        return 0;
err_ret:
        return ret;
}

int main(int argc, char *argv[])
{
        int ret, count, args = 1;
        const char *home;

        if (argc < 3) {
                fprintf(stderr, "test_clock /clock_home/ clock_count\n");
                EXIT(1);
        } else {
                home = argv[args++];
                count = atoi(argv[args++]);
        }

        ret = conf_init();
        if (unlikely(ret))
                GOTO(err_ret, ret);

        printf("test in %s, count %d\n", home, count);

        ret = cpuset_init();
        if (unlikely(ret))
                GOTO(err_ret, ret);

        ret = clock_init(10240);
        if (unlikely(ret))
                GOTO(err_ret, ret);

        ret = test_clock_set_start(0, count);
        if (unlikely(ret))
                GOTO(err_ret, ret);

        /*ret = test_clock_set_start(1);*/
        /*if (unlikely(ret))*/
                /*GOTO(err_ret, ret);*/

        sleep(100000);

        return 0;
err_ret:
        return ret;
}
